package com.weilele.mvvm.utils.result_contract

import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContract
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityOptionsCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import com.weilele.mvvm.base.MvvmActivity
import com.weilele.mvvm.base.MvvmDialog
import com.weilele.mvvm.base.MvvmFragment
import com.weilele.mvvm.base.helper.ILifecycleObserver
import com.weilele.mvvm.base.livedata.appCompatActivity
import com.weilele.mvvm.utils.printIntent

class NavigateForResultHelper : ILifecycleObserver, ActivityResultCallback<Intent?>,
    ActivityResultContract<Intent, Intent?>() {
    companion object {
        operator fun invoke(appCompatActivity: AppCompatActivity): NavigateForResultHelper {
            return NavigateForResultHelper().apply {
                appCompatActivity.lifecycle.addObserver(this)
            }
        }

        operator fun invoke(fragment: Fragment): NavigateForResultHelper {
            return NavigateForResultHelper().apply {
                fragment.lifecycle.addObserver(this)
            }
        }
    }

    private var launcher: ActivityResultLauncher<Intent?>? = null
    private var resultListener: ((resultCode: Int, intent: Intent?) -> Unit)? = null

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        launcher = when (owner) {
            is AppCompatActivity -> {
                owner.registerForActivityResult(this, this)
            }
            is Fragment -> {
                owner.registerForActivityResult(this, this)
            }
            else -> {
                null
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        launcher?.unregister()
        launcher = null
    }

    override fun onActivityResult(result: Intent?) {
        printIntent { result }
    }

    override fun createIntent(context: Context, input: Intent): Intent {
        return input
    }

    override fun parseResult(resultCode: Int, intent: Intent?): Intent? {
        resultListener?.invoke(resultCode, intent)
        return intent
    }

    fun navigateForResult(
        intent: Intent,
        option: ActivityOptionsCompat? = null,
        onResult: (resultCode: Int, intent: Intent?) -> Unit
    ) {
        resultListener = onResult
        launcher?.launch(intent, option)
    }
}

inline fun <reified A : Activity> MvvmActivity.navigateForResult(
    intent: Intent? = null,
    option: ActivityOptionsCompat? = null,
    noinline setParams: ((Intent) -> Unit)? = null,
    noinline onResult: (resultCode: Int, intent: Intent?) -> Unit
) {
    val i = intent ?: Intent(this, A::class.java)
    setParams?.invoke(i)
    navigateForResultHelper.navigateForResult(i, option, onResult)
}

inline fun <reified A : Activity> MvvmFragment.navigateForResult(
    intent: Intent? = null,
    option: ActivityOptionsCompat? = null,
    noinline setParams: ((Intent) -> Unit)? = null,
    noinline onResult: (resultCode: Int, intent: Intent?) -> Unit
) {
    val i = intent ?: Intent(appCompatActivity, A::class.java)
    setParams?.invoke(i)
    navigateForResultHelper.navigateForResult(i, option, onResult)
}

inline fun <reified A : Activity> MvvmDialog.navigateForResult(
    intent: Intent? = null,
    option: ActivityOptionsCompat? = null,
    noinline setParams: ((Intent) -> Unit)? = null,
    noinline onResult: (resultCode: Int, intent: Intent?) -> Unit
) {
    val i = intent ?: Intent(appCompatActivity, A::class.java)
    setParams?.invoke(i)
    navigateForResultHelper.navigateForResult(i, option, onResult)
}




